# -*- coding: utf-8 -*-

# 图层控制系统继承自QListWidget,因此要先引入相关组件
from PyQt5.QtWidgets import (
    QListWidget,
    QListWidgetItem,
    QAction,
    QMenu,
    QAbstractItemView
)

# 引入QtGui模块
from PyQt5.QtGui import (
    QIcon
)

# 引入QtCore模块
from PyQt5.QtCore import (
    Qt,
    QSize,
    QObject,
    pyqtSignal
)

# 导入枚举类
from enum import Enum

# 枚举类，用来过滤右键菜单的弹出项
class QActionType(Enum):
    ALL = 0 # 所有的图层
    Vector = 1 # 矢量图层
    Raster = 2 # 栅格图层


class QActionItem:
    def __init__(self,type:QActionType,action:QAction):
        """
        初始化右键菜单项
        param: type: QActionType
        param: action: QAction
        """
        self.type = type
        self.action = action

class TocItem(QListWidgetItem):
    def __init__(self,title:str,icon:QIcon,obj:QObject,parent:QListWidget = None):
        """
        初始化图层项
        param: title: 图层标题
        param: icon: 图层图标
        param: obj: 图层对象
        """
        super(TocItem,self).__init__(parent)
        self.__m_obj = obj
        self.setCheckState(Qt.Checked)
        self.setIcon(icon)
        self.setText(title)
        self.setSizeHint(QSize(360,26))

    def GetObject(self):
        """
        获取对象
        return: QObject
        """
        return self.__m_obj
    
    def SetObject(self,obj:QObject):
        """
        设置对象
        param: obj: QObject
        """
        self.__m_obj = obj



class TocControl(QListWidget):
    """
    图层控制器，控制图层列表
    """

    rowsMove = pyqtSignal(int,int) # 图层列表拖动信号槽

    selectAction = pyqtSignal(str,TocItem)

    def __init__(self,parent=None):
        """
        初始化图层列表
        """
        super(TocControl,self).__init__(parent)
        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.setDragDropMode(QAbstractItemView.InternalMove)
        self.setDropIndicatorShown(True)
        self.setDragDropOverwriteMode(False)
        self.__m_show_menu = False
        self.__m_action_items = []
    
    def AddAction(self,type:QActionType,actionName:str):
        """
        添加右键菜单项
        param: type: QActionType
        """
        action = QAction(actionName,self)
        self.__m_action_items.append(QActionItem(type,action))

    def ShowMenuTip(self,isshow:bool):
        """
        设置是否显示右键菜单
        param: isshow: bool
        """
        self.__m_show_menu = isshow
    
    def __findbyObject(self,obj:object):
        """
        查找对象
        param: obj: object
        return: int 返回对象索引
        """
        for i in range(self.count()):
            item:TocItem = self.item(i)
            if item.GetObject() == obj:
                return i
        return -1
    
    def dropEvent(self, e):
        """
        重写拖动事件
        """
        # super(TocControl, self).dropEvent(e)# 确保不插入空白项

        index = self.indexAt(e.pos())

        if not index.isValid():
            e.setDropAction(Qt.IgnoreAction)
            return
        
        idxs = self.selectedIndexes()
        startIndex = idxs[0].row()

        endIndex = startIndex

        dropIndicationPos = self.dropIndicatorPosition()

        if dropIndicationPos == QAbstractItemView.AboveItem:
            endIndex = index.row()
        elif dropIndicationPos == QAbstractItemView.BelowItem:
            endIndex = index.row() + 1

        
        if startIndex != endIndex:
            if startIndex < endIndex:
                endIndex = endIndex - 1

            if startIndex != endIndex:
                super(TocControl, self).dropEvent(e)# 确保不插入空白项
                self.rowsMove.emit(startIndex,endIndex) # 发送拖动信号


    
    def contextMenuEvent(self, event):
        """
        重写右键菜单事件
        """

        index  = self.indexAt(event.pos())

        if not index.isValid(): 
            return
        
        item = self.item(index.row())

        if isinstance(item,TocItem):
            qe_item:TocItem = item

            if self.__m_show_menu:
                menu = QMenu(self)

                if qe_item.GetObject().__class__.__name__ == 'QgsVectorLayer':
                    for item in self.__m_action_items:
                        if item.type == QActionType.Vector or item.type == QActionType.ALL:
                            menu.addAction(item.action)
                else:
                    for item in self.__m_action_items:
                        if item.type == QActionType.Raster or item.type == QActionType.ALL:
                            menu.addAction(item.action)
                    
                select_action = menu.exec(event.globalPos())

                if select_action is not None:
                    self.selectAction.emit(select_action.text(),qe_item)
            else:
                event.ignore()
        else:
            event.ignore()